// StructSnapshotDlg.cpp : implementation file
//

#include "stdafx.h"
#include "StructSnapshot.h"
#include "StructSnapshotDlg.h"

#include "TreeManager.h"
#include "ftNode.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

#define WM_UPDATESIZE WM_USER+1
#define WM_UPDATEPATH WM_USER+2

/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About

class CAboutDlg : public CDialog
{
public:
	CAboutDlg();

// Dialog Data
	//{{AFX_DATA(CAboutDlg)
	enum { IDD = IDD_ABOUTBOX };
	//}}AFX_DATA

	// ClassWizard generated virtual function overrides
	//{{AFX_VIRTUAL(CAboutDlg)
	protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
	//}}AFX_VIRTUAL

// Implementation
protected:
	//{{AFX_MSG(CAboutDlg)
	//}}AFX_MSG
	DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
	//{{AFX_DATA_INIT(CAboutDlg)
	//}}AFX_DATA_INIT
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CAboutDlg)
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
	//{{AFX_MSG_MAP(CAboutDlg)
		// No message handlers
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CStructSnapshotDlg dialog

CStructSnapshotDlg::CStructSnapshotDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CStructSnapshotDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CStructSnapshotDlg)
	m_csSnapPath = _T("");
	m_csPath = _T("");
	//}}AFX_DATA_INIT
	// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
	//get current path
	GetModuleFileName(NULL, m_csCurPath.GetBuffer(MAX_PATH), MAX_PATH);
	m_csCurPath.ReleaseBuffer();
	m_csCurPath = m_csCurPath.Left(m_csCurPath.ReverseFind('\\'));

}

void CStructSnapshotDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CStructSnapshotDlg)
	DDX_Text(pDX, IDC_EDIT_SNAPPATH, m_csSnapPath);
	DDX_Text(pDX, IDC_EDIT_PATH, m_csPath);
	//}}AFX_DATA_MAP
	DDX_Control(pDX, IDC_TREE, m_ctrTree);
	DDX_Control(pDX, IDC_CHART_BASE, m_ctrOnionChart);
	DDX_Control(pDX, IDC_EDIT, m_ctrEdit);
	DDX_Text(pDX, IDC_EDIT, m_editPath);
}

BEGIN_MESSAGE_MAP(CStructSnapshotDlg, CDialog)
	//{{AFX_MSG_MAP(CStructSnapshotDlg)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_BN_CLICKED(IDC_BTN_START, OnBtnStart)
	//}}AFX_MSG_MAP
	ON_MESSAGE(WM_UPDATESIZE, OnUpdateSize)
	ON_MESSAGE(WM_UPDATEPATH, OnUpdatePath)
	ON_WM_QUERYENDSESSION()
	ON_WM_ENDSESSION()
	ON_BN_CLICKED(IDOK, &CStructSnapshotDlg::OnBnClickedOk)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CStructSnapshotDlg message handlers

BOOL CStructSnapshotDlg::OnInitDialog()
{
	CDialog::OnInitDialog();

	// Add "About..." menu item to system menu.

	// IDM_ABOUTBOX must be in the system command range.
	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
	ASSERT(IDM_ABOUTBOX < 0xF000);

	CMenu* pSysMenu = GetSystemMenu(FALSE);
	if (pSysMenu != NULL)
	{
		CString strAboutMenu;
		strAboutMenu.LoadString(IDS_ABOUTBOX);
		if (!strAboutMenu.IsEmpty())
		{
			pSysMenu->AppendMenu(MF_SEPARATOR);
			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
		}
	}

	// Set the icon for this dialog.  The framework does this automatically
	//  when the application's main window is not a dialog
	SetIcon(m_hIcon, TRUE);			// Set big icon
	SetIcon(m_hIcon, FALSE);		// Set small icon
	
	// TODO: Add extra initialization here
	m_csSnapPath = _T("D:\\APISDK\\");
	m_editPath = _T("aaa");
	UpdateData(FALSE);

//	m_ctrOnionChart.LoadTree(&m_treeManager);
	//m_ctrOnionChart.addlevel(4);
	//m_ctrOnionChart.getlevel(1)->total = 1000;
	//for (int j=0; j< 6; j++)
	//{
	//	m_ctrOnionChart.additem(1, 100);
	//}
	//m_ctrOnionChart.getlevel(2)->total = 400;
	//for (int j=0; j< 3; j++)
	//{
	//	m_ctrOnionChart.additem(2, 23);
	//}
	//m_ctrOnionChart.getlevel(3)->total = 1000;
	//for (int j=0; j< 4; j++)
	//{
	//	m_ctrOnionChart.additem(3, 155);
	//}

	//m_ctrOnionChart.CountLevelSize();


	return TRUE;  // return TRUE  unless you set the focus to a control
}

void CStructSnapshotDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
	if ((nID & 0xFFF0) == IDM_ABOUTBOX)
	{
		CAboutDlg dlgAbout;
		dlgAbout.DoModal();
	}
	else
	{
		CDialog::OnSysCommand(nID, lParam);
	}
}

// If you add a minimize button to your dialog, you will need the code below
//  to draw the icon.  For MFC applications using the document/view model,
//  this is automatically done for you by the framework.

void CStructSnapshotDlg::OnPaint() 
{
	if (IsIconic())
	{
		CPaintDC dc(this); // device context for painting

		SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);

		// Center icon in client rectangle
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// Draw the icon
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialog::OnPaint();
	}
}

// The system calls this to obtain the cursor to display while the user drags
//  the minimized window.
HCURSOR CStructSnapshotDlg::OnQueryDragIcon()
{
	return (HCURSOR) m_hIcon;
}

void CStructSnapshotDlg::OnBtnStart() 
{
	// TODO: Add your control notification handler code here
	UpdateData(TRUE);
	CWinThread* pThread = AfxBeginThread(TraversePath, this);	
}

LRESULT CStructSnapshotDlg::OnUpdateSize(WPARAM wParam, LPARAM lParam)
{
	m_csPath = TranslateSizeToStr(wParam, lParam);
	UpdateData(FALSE);
	return TRUE;
}

LRESULT CStructSnapshotDlg::OnUpdatePath(WPARAM wParam, LPARAM lParam)
{
	ftNode* pNode = (ftNode*)wParam;
	if (pNode != NULL)
	{
		m_editPath += pNode->m_csName;
		m_editPath += _T(";\x0d\x0a");
		UpdateData(FALSE);
	}
	return TRUE;
}
CString CStructSnapshotDlg::TranslateSizeToStr(DWORD nSizeHigh, DWORD nSizeLow, int nSizeType)
{
	LARGE_INTEGER llSize;
	llSize.HighPart = nSizeHigh;
	llSize.LowPart = nSizeLow;
	switch(nSizeType)
	{
	case ST_AUTO:	
	case ST_BYTE:
		break;
	case ST_KB:
		llSize.QuadPart /= 0x400;
		break;
	case ST_MB:
		llSize.QuadPart /= 0x100000;
	    break;
	case ST_GB:
		llSize.QuadPart /= 0x40000000;
	    break;
	case ST_TB:
		llSize.QuadPart /= 0x10000000000;	
		break;
	default:
	    break;
	}
	CString csSize;
	csSize.Format(_T("%I64d"),llSize.QuadPart);

	CString csRet;
	int nLen = csSize.GetLength();
	if (nLen>3)
	{
		int i;
		csRet = csSize.Mid(nLen-3,3);
		for (i=nLen-6; i>=0; i-=3)
		{
			csRet = csSize.Mid(i,3) + _T(",") +csRet;
			if (i<3)
			{
				csRet = csSize.Mid(0,i) + _T(",") +csRet;
			}
		}
	}
	return csRet;
}

UINT TraversePath( LPVOID pParam )
{
	CStructSnapshotDlg* pDlg = (CStructSnapshotDlg*)pParam;
	ASSERT(NULL != pDlg);
	pDlg->m_treeManager.CreateTree(pDlg->m_csSnapPath, TraverseCallback, pDlg->GetSafeHwnd());
	pDlg->m_ctrOnionChart.LoadTree(&pDlg->m_treeManager);
	pDlg->Invalidate();
	return 0;
}

void TraverseCallback( DWORD dwSizeHigh, DWORD dwSizeLow, DWORD lParam, PVOID rParam)
{
	HWND hWnd = (HWND)rParam;
	ASSERT(NULL != hWnd);
	PostMessage(hWnd, WM_UPDATESIZE, dwSizeHigh, dwSizeLow);
	PostMessage(hWnd, WM_UPDATEPATH, lParam, NULL);
}

BOOL CStructSnapshotDlg::PreTranslateMessage(MSG* pMsg)
{
	// TODO: Add your specialized code here and/or call the base class
	if(pMsg->message == WM_KEYDOWN)
	{
		CWnd* pFocusWnd;
		switch (pMsg->wParam)
		{
		case VK_RETURN:
			//do Enter do
			pFocusWnd = GetFocus();
			if (pFocusWnd != NULL)
			{
				CString csClassname;
				GetClassName (pFocusWnd->m_hWnd, csClassname.GetBuffer(32), 32);
				csClassname.ReleaseBuffer();
				if (_T("Button") == csClassname)
				{
					//SendMessage(pMsg->message, pMsg->wParam, pMsg->lParam);
					UINT i = pFocusWnd->GetDlgCtrlID();
					SendMessage (WM_COMMAND, i, (LPARAM)pFocusWnd->m_hWnd);
					//return TRUE;
				}
			}
			//break;
		case VK_ESCAPE:
			return TRUE;
			break;
		default:
			break;
		}
	}
	return CDialog::PreTranslateMessage(pMsg);
}

BOOL CStructSnapshotDlg::OnQueryEndSession()
{
	if (!CDialog::OnQueryEndSession())
		return FALSE;

	// TODO:  Add your specialized query end session code here

	return TRUE;
}

void CStructSnapshotDlg::OnEndSession(BOOL bEnding)
{
	CDialog::OnEndSession(bEnding);

	// TODO: Add your message handler code here
	PostQuitMessage(0);
}

void CStructSnapshotDlg::OnBnClickedOk()
{
	// TODO: Add your control notification handler code here
	OnOK();
}
